/**
 * 类装饰器工厂函数\
 * 返回一个类装饰器
 */
function logClassWithPrams(message: string) {
  /**
   * 类装饰器接收一个参数是构造函数本身
   */
  return function (constructor: Function) {
    console.log(constructor.name, message)
  }
}
@logClassWithPrams('class-created')
class Car {}


// 接口会合并到类上
// interface Document {
//   timestamp: Date
// }
// // 类装饰器来重写类 扩展类的属性
// function addTimestamp<T extends { new(...args: any[]): {} }>(constructor: T) {
//   return class extends constructor {
//     timestamp = new Date() // 当前时间戳
//   }
// }
// @addTimestamp
// class Document {
//   constructor(public title: string) { }
// }
// const doc = new Document('my document')
// console.log(doc.title, doc.timestamp)


// 使用类装饰器重写构造函数
function replaceConstructor<T extends {new (...args: any[]): {}}> (constructor: T) {
  // 通过 extends 继承原始类的行为
  // 返回一个添加了额外逻辑的新类
  // 由于改写了默认的构造函数 replaceConstructor 类装饰器装饰的类会在实例化一个对象时调用
  return class extends constructor {
    constructor(...args: any[]) {
      // 过 super(...args) 调用父类构造函数，可以确保新类实例能够继承原类的构造逻辑
      super(...args) // 调用被装饰的类
      console.log('User 被装饰的类的额外逻辑')
    }
  }
}
@replaceConstructor
class User {
  constructor(public name: string) {
    console.log('User 构造函数自身的逻辑')
  }
}

const user = new User('John Doe')

console.log(Object.getPrototypeOf(user) === User.prototype) // true
console.log(user.name)

// 使用 export 来表示当前 TS 文件是一个模块
export { }
